package com.github.chirspan.xaas.cfg.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.chirspan.xaas.cfg.dao.CfgConfigDao;
import com.github.chirspan.xaas.cfg.model.CfgApp;
import com.github.chirspan.xaas.cfg.service.ICfgAppService;
import com.github.chirspan.xaas.cfg.service.ICfgConfigService;
import com.github.chirspan.xaas.cfg.model.CfgConfig;
import com.github.chirspan.xaas.core.cache.CfgCache;
import com.github.chirspan.xaas.core.constant.XaasConstants;
import com.github.chirspan.xaas.mybatis.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Set;

/**
 * @Author: chenpan
 * @Date: 2021-04-07 18:24:53
 * @Description: 应用配置 接口实现
 */
@Service
public class CfgConfigServiceImpl extends BaseServiceImpl<CfgConfigDao, CfgConfig> implements ICfgConfigService {

    @Autowired
    private ICfgAppService appService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @CacheEvict(value = "cfg", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public boolean add(CfgConfig entity) {
        removeAppCache(entity.getAppId());
        return super.add(entity);
    }

    @Override
    @Cacheable(value = "cfg", key = "#p0+'_'+#p1", unless = "#result == null")
    @Transactional(rollbackFor = Exception.class)
    public String getConfigByAppAndCode(String appCode, String configCode) {
        CfgApp app = appService.getAppByCode(appCode);
        if (app == null) {
            return null;
        }
        LambdaQueryWrapper<CfgConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CfgConfig::getAppId, app.getId())
                .eq(CfgConfig::getConfigCode, configCode);
        CfgConfig config = baseMapper.selectOne(queryWrapper);
        if (config != null) {
            return config.getConfigValue();
        }
        return null;
    }

    @Override
    @CacheEvict(value = "cfg", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(String id) {
        CfgConfig config = super.selectById(id);
        removeAppCache(config.getAppId());
        return super.delete(id);
    }

    @Override
    @CacheEvict(value = "cfg", allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public boolean updateNotNull(CfgConfig entity) {
        removeAppCache(entity.getAppId());
        return super.updateNotNull(entity);
    }

    private void removeAppCache(String appId) {
        CfgApp app = appService.selectById(appId);
        if (app == null) {
            return;
        }
        String keyMatch = StrUtil.join(XaasConstants.CACHE_SEPARATOR, XaasConstants.CACHE_KEY_PREFIX,
                app.getAppCode(), CfgCache.CFG_CACHE_KEY);
        Set<String> keys = redisTemplate.keys(keyMatch + "*");
        if (CollectionUtil.isNotEmpty(keys)) {
            redisTemplate.delete(keys);
        }
    }
}